﻿/*
* 创建者：LIYINFAI
* 创建时间：2023/12/20 10:12:44
* 描述：SocketClientHelper
* --------------------------------------
* 修改说明：
* --------------------------------------
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;

namespace CommonLibrary
{
    /// <summary>
    /// 套接字客户端操作类
    /// </summary>
    public class SocketClientHelper
    {
        private bool mIsConnected = false;
        /// <summary>
        /// 是否连接
        /// </summary>
        public bool IsConnected
        {
            get
            {
                if (!this.mIsConnected || this.mSocket == null || !this.mSocket.Connected)
                {
                    this.mSocket.Close();
                    this.mSocket = null;
                    this.CheckConnect();
                }
                return this.mIsConnected;
            }
        }

        private Socket mSocket = null;
        private TcpEntity mTcpEntity { get; set; } = null;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public SocketClientHelper(string ip, int port) : this(new TcpEntity()
        {
            IP = ip,
            Port = port
        })
        {

        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="tcpEntity"></param>
        public SocketClientHelper(TcpEntity tcpEntity)
        {
            this.mTcpEntity = tcpEntity;
            if (this.mTcpEntity != null)
            {
                this.CheckConnect();
            }
        }
        private void CheckConnect()
        {
            if (this.mSocket == null)
            {
                this.mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                var asyncResult = this.mSocket.BeginConnect(this.mTcpEntity.IP, this.mTcpEntity.Port, null, null);
                bool success = asyncResult.AsyncWaitHandle.WaitOne(500, true);
                if (this.mSocket.Connected)
                {
                    this.mSocket.EndConnect(asyncResult);
                }
                this.mIsConnected = this.mSocket.Connected;
            }
        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="data"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SendData(byte[] data, int timeout = 1000)
        {
            bool result = false;
            if (this.IsConnected && data != null && data.Length > 0)
            {
                try
                {
                    LogHelper.Info($"【往服务端发送数据】{this.mTcpEntity} {string.Join(" ", data.Select(v => v.ToString("X2")))}");
                    this.mSocket.SendTimeout = timeout;
                    int len = this.mSocket.Send(data);
                    result = len == data.Length;
                    LogHelper.Info($"【往服务端发送数据】{this.mTcpEntity} 发送结果：{len == data.Length}");
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex, string.Empty, $"【往服务端发送数据】{this.mTcpEntity}");
                }
            }
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="timeout">默认2秒</param>
        /// <returns></returns>
        public (bool success, byte[] data) Receive(int timeout = 2000)
        {
            bool success = false;
            List<byte> data = new List<byte>();
            if (this.IsConnected)
            {
                try
                {
                    this.mSocket.ReceiveTimeout = timeout;
                    while (true)
                    {
                        byte[] buffer = new byte[1024];
                        int len = this.mSocket.Receive(buffer);
                        if (len < buffer.Length)
                        {
                            if (len > 0)
                            {
                                data.AddRange(buffer.Take(len));
                            }
                            break;
                        }
                        else
                        {
                            data.AddRange(buffer);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex, string.Empty, $"【从服务端读取数据】{this.mTcpEntity}");
                }
            }
            return (success, data.Count == 0 ? null : data.ToArray());
        }

        /// <summary>
        /// 析构函数
        /// </summary>
        ~SocketClientHelper()
        {
            if (this.mSocket != null)
            {
                try
                {
                    this.mSocket.Close();
                    this.mSocket = null;
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex);
                }
            }
        }
    }
}
